home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Tools & Apps / Testing & Debugging / Robix V1.0 / robix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-21  |  17.1 KB  |  702 lines  |  [TEXT/MPS ]

  1. /*
  2. *
  3. * © Copyright 1991, Rob Glanville
  4. *
  5. * by Rob Glanville
  6. *
  7. * 8 May 91
  8. *
  9. * robix.c - Super debugger
  10. *
  11. */
  12.  
  13. #include "robix.h"
  14. #include <stdio.h>
  15. #include <Slots.h>
  16. #include <OSUtils.h>
  17.  
  18. /************************************* Defines ***********************************************/
  19.  
  20. #define SONIC        0x00900000
  21. #define ENetAddress    0x00700000
  22. #define ENet1        0x00        /* Logical label for a logical slot */
  23. #define ENet2        0x01        /* Logical label for a logical slot */
  24. #define Command        0x400        /* Channel Command byte */
  25. #define Flags        0x401        /* Channel flags */
  26. #define Count        0x402        /* Count word */
  27. #define BufferPtr    0x404        /* Address pointer */
  28. #define    PBYTE        *(unsigned char *)    /* Used for physical address casting */
  29. #define    PWORD        *(unsigned short *)    /* Used for physical address casting */
  30. #define    PLONG        *(unsigned long *)    /* Used for physical address casting */
  31. #define ResetMCP    0x00F00000
  32. #define StartMCP    0x00C00000
  33. #define TxBuffer    0x008000    // Transmit buffer
  34. #define RxBuffer    0x00A000    // Receive buffer area 1
  35.  
  36. /* Flag bits */
  37. #define F_ready            0x80            /* Ready                            */
  38. #define F_datachain        0x40            /* DataChain                        */
  39. #define F_update        0x20            /* Update                            */
  40. #define F_interrupt        0x10            /* Interrupt                        */
  41. #define F_timer            0x08            /* TimerInt                            */
  42. #define F_aborted        0x04            /* Aborted                            */
  43. #define F_overrun        0x02            /* Overrun                            */
  44. #define F_size            0x01            /* 0=byte, 1=word                    */
  45.  
  46. /************************************* Variables *********************************************/
  47.  
  48. UBYTE CommandLine[256];    /* Input buffer                                */
  49. UBYTE delimiter;        /* Delimiter between arguments                */
  50. UBYTE AsciiBuf[19];        /* A buffer for output                        */
  51. UBYTE Argument[0x80];    /* The arguments go here one by one            */
  52. UBYTE TabSize;            /* Size of tab stops                        */
  53. UBYTE origMMUMode;        /* The original MMU mode                    */
  54. UBYTE RobSlot;
  55.  
  56. UWORD ArgSize;            /* Argument size                            */
  57. UWORD CPointer;            /* Command pointer                            */
  58. UWORD slotPtr;            /* A logical index to the slot where 1=9    */
  59.  
  60. ULONG CommandIndex;        /* The index into command buffer            */
  61. ULONG number;            /* A place for all numbers input            */
  62. ULONG SlotMngrID;        /* Slot manager ID                            */
  63. ULONG InfoPointer;        /* Slot Information pointer                    */
  64. ULONG BufPtr;            /* Alias buffer pointer for unions            */
  65. ULONG RobBase;
  66.  
  67. ilong err;                /* Standard error code for Macintosh        */
  68. ULONG slot24Bit[6];        /* 24 bit slot addresses for first megabyte    */
  69. UBYTE *slotBases[6];    /* 32 bit slot addresses for above 1MB        */
  70. ULONG slotCount;        /* Number of active slots                    */
  71.  
  72. /*
  73. * Only portions of this structure are used, the rest are just place holders
  74. */
  75. struct {
  76.     ULONG a,b,c,d,e,f,g,h,i;
  77.     UWORD j,k,spCatagory,spCType,spDrvrSW,spDrvrHW;
  78.     UBYTE p,spSlot,spID,s,t,u,v,w;
  79.     } SlotBlock;
  80.  
  81. /* Transmit buffer */
  82. struct {
  83.     UBYTE Destination[6];
  84.     UBYTE Source[6];
  85.     UWORD Length;
  86.     UBYTE Buffer[1500];
  87.     UWORD CRCPad;
  88.     } TxPacket;
  89.     
  90. /* Receive buffer */
  91. struct {
  92.     UBYTE Destination[6];
  93.     UBYTE Source[6];
  94.     UWORD Length;
  95.     UBYTE Buffer[1500];
  96.     UWORD CRC;
  97.     } RxPacket;
  98.  
  99. /************************************* Constants *********************************************/
  100.  
  101. UBYTE Digits[]     = {"0123456789ABCDEF"};
  102. UBYTE Delimiters[] = {0x09,0x0a,0x1b,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
  103.                       0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x3a,
  104.                       0x3b,0x3c,0x3d,0x3e,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,
  105.                       0x00,0x60,0x7b,0x7c,0x7d,0x7e,0x7f,0x3f,0x0d};
  106.  
  107. struct {
  108.     UBYTE Address[6]; /* Slot 9 is another type of Ethernet card */
  109.     } Node [5] = {0x10,0x00,0xE0,0x28,0x08,0x77, /* Slot A card */
  110.                   0x10,0x00,0xE0,0x28,0x03,0x40, /* Slot B card */
  111.                   0x10,0x00,0xE0,0x28,0x08,0x77, /* Slot A card */
  112.                   0x10,0x00,0xE0,0x28,0x08,0xEB, /* Slot D card */
  113.                   0x10,0x00,0xE0,0x28,0x06,0xF9};/* Slot E card */
  114.                   
  115. /************************************* Externals *********************************************/
  116.  
  117. extern    UWORD GetWord(UWORD *);
  118. extern    void PutWord(UWORD *,UWORD);
  119. extern    UBYTE SONICMenu();
  120. extern    BEGIN();
  121. extern    BuildPacket(UBYTE,UBYTE,UWORD);
  122.  
  123. /************************************* Routines **********************************************/
  124.  
  125. void ReportError(err) ilong err; {
  126.     switch(err) {
  127.         case 0x00 :
  128.             printf("No error\n");
  129.             break;
  130.         case -344 :
  131.             printf("No resource available\n");
  132.             break;
  133.         default :
  134.             printf("Internal program error, Undefined err number = %-d\n",err);
  135.             break;
  136.         }
  137.     }
  138.  
  139. void SyntaxError() {
  140.     printf("Syntax error\n");
  141.     }
  142.  
  143. unsigned char getch() {
  144.     unsigned char character;
  145.     do {
  146.         character = getchar();
  147.         } while (character == 0xff);
  148.     return(character);
  149.     }
  150.  
  151. void LineIn() {
  152.     UBYTE character,exit;
  153.     UWORD index,TabSpace;
  154.     if (delimiter == CR) {
  155.         CommandIndex = Null;
  156.         exit = False;
  157.         CPointer = Null;
  158.         do {
  159.             character = getch();
  160.             if (character ==  Rubout) {
  161.                 if (CommandIndex > 0) {
  162.                     putchar(Rubout);
  163.                     putchar(Blank);
  164.                     putchar(Rubout);
  165.                     CommandIndex--;
  166.                     }
  167.                 }
  168.             else if (character == CR) {
  169.                 putchar(CR);
  170.                 CommandLine[CommandIndex++] = CR;
  171.                 exit = True;        
  172.                 }
  173.             else if (character == Tab) {
  174.                 TabSpace = TabSize - ((CommandIndex+1) % TabSize);
  175.                 for (index=0;index<TabSpace;index++) {
  176.                     putchar(Blank);
  177.                     CommandLine[CommandIndex++] = Blank;
  178.                     }
  179.                 }
  180.             else {
  181. /*                putchar(character); */
  182.                 CommandLine[CommandIndex++] = character;
  183.                 }
  184.             } while (!exit);
  185.         }
  186.     else delimiter = CR;
  187.     }
  188.  
  189. void Upper(character) UBYTE *character; {
  190.     if ((*character >= 'a') && (*character <= 'z')) *character -= Blank;
  191.     }
  192.  
  193. void ScanDelimiters() {
  194.     UWORD index;
  195.     UBYTE found;
  196.     do {
  197.         found = False;
  198.         for (index=0;index<sizeof(Delimiters)-2;index++) {
  199.             if (CommandLine[CPointer] == Delimiters[index]) found = True;
  200.             }
  201.         if (found) CPointer++;
  202.         } while (found);
  203.     }
  204.  
  205. void getarg() {
  206.     UWORD index,ArgPtr;
  207.     UBYTE found;
  208.     ArgPtr = Null;
  209.     do {
  210.         found = False;
  211.         for (index=0;index<sizeof(Delimiters);index++) {
  212.             if (CommandLine[CPointer] == Delimiters[index]) {
  213.                 delimiter = Delimiters[index];
  214.                 if (delimiter != CR) CPointer++;
  215.                 found = True;
  216.                 break;
  217.                 }
  218.             }
  219.         if (!found) Argument[ArgPtr++] = CommandLine[CPointer++];
  220.         } while (!found);
  221.     Argument[ArgPtr] = Null;
  222.     ArgSize = ArgPtr;
  223.     }
  224.  
  225. UWORD GetValue() {
  226.     UBYTE found;
  227.     UWORD index,loop;
  228.     if (delimiter == ',') return(False);
  229.     found = False;
  230.     number = Null;
  231.     do {
  232.         getarg(); /* Get one argument from the command line */
  233.         if (ArgSize) {
  234.             /* Check for all digits in the argument */
  235.             for (index=0;index<ArgSize;) {
  236.                 Upper(&Argument[index]);
  237.                 found = False;
  238.                 for (loop=0;loop<0x10;loop++) {
  239.                     if (Argument[index] == Digits[loop]) {
  240.                         Argument[index] = loop;
  241.                         found = True;
  242.                         break;
  243.                         }
  244.                     }
  245.                 if (!found) break;
  246.                 else index++;
  247.                 }
  248.             /* Convert ascii to hex */
  249.             if (found) for (index=0;index<ArgSize;index++) {
  250.                 number = ((number * 0x10) + Argument[index]);
  251.                 }
  252.             }
  253.         } while ((!found) && (delimiter != CR) && (delimiter != ','));
  254.     return(found);
  255.     }
  256.  
  257. void nibble(data) UBYTE data; {
  258.     if (data > 9) putchar(data + '7');
  259.     else putchar(data + '0');
  260.     }
  261.  
  262. void byteout(data) UBYTE data; {
  263.     nibble((data / 0x10) & 0x0f);
  264.     nibble(data & 0x0f);
  265.     }
  266.  
  267. void wordout(data) UWORD data; {
  268.     byteout((UBYTE)(data / 0x100) & 0xff);
  269.     byteout((UBYTE)data & 0xff);
  270.     }
  271.  
  272. void longout(data) ULONG data; {
  273.     wordout((UWORD)(data / 0x10000) & 0xffff);
  274.     wordout((UWORD)data & 0xffff);
  275.     }
  276.  
  277. void crlf() { printf("\n"); }
  278.  
  279. /************************************* Commands *********************************************/
  280.     
  281. UWORD AlterMemory() {
  282.     ULONG Address;
  283.     UBYTE databyte,origMMUMode;
  284.     if (!GetValue()) return(True);
  285.     Address = number;
  286.     origMMUMode = true32b;
  287.     if (GetValue()) {
  288.         SwapMMUMode(&origMMUMode);
  289.         do {
  290.             *(UBYTE *)Address++ = number;
  291.             } while (GetValue());
  292.         SwapMMUMode(&origMMUMode);
  293.         return(False);
  294.         }
  295.     else while(True) {
  296.         longout(Address);
  297.         putchar(Blank);
  298.         SwapMMUMode(&origMMUMode);
  299.         databyte = *(UBYTE *)Address;
  300.         SwapMMUMode(&origMMUMode);
  301.         byteout(databyte);
  302.         putchar('-');
  303.         LineIn();
  304.         ScanDelimiters();
  305.         if (!GetValue()) return(False);
  306.         SwapMMUMode(&origMMUMode);
  307.         *(UBYTE *)Address++ = number;
  308.         SwapMMUMode(&origMMUMode);
  309.         }
  310.     }
  311.  
  312. UWORD AlterWordMemory() {
  313.     UBYTE origMMUMode;
  314.     UWORD dataword;
  315.     ULONG Address;
  316.     if (!GetValue()) return(True);
  317.     Address = number;
  318.     origMMUMode = true32b;
  319.     if (GetValue()) {
  320.         SwapMMUMode(&origMMUMode);
  321.         do {
  322.             *(UWORD *)Address = number;
  323.             Address += 2;
  324.             } while (GetValue());
  325.         SwapMMUMode(&origMMUMode);
  326.         }
  327.     else {
  328.         longout(Address);
  329.         putchar(Blank);
  330.         SwapMMUMode(&origMMUMode);
  331.         dataword = *(UWORD *)Address;
  332.         SwapMMUMode(&origMMUMode);
  333.         wordout(dataword);
  334.         crlf();
  335.         }
  336.     return(False);
  337.     }
  338.  
  339. UWORD DisplayMemory() {
  340.     ULONG Start,Length,index,Aindex,Sindex;
  341.     register UBYTE databyte;
  342.     UBYTE origMMUMode;
  343.     if (!GetValue()) return(True);
  344.     Start = number;
  345.     if (GetValue()) Length = number;
  346.     else Length = 0x10;
  347.     if (Length == 0) Length = 1;
  348.     origMMUMode = true32b;
  349.     index = Null;
  350.     Aindex = Null;
  351.     do {
  352.         if ((index % 0x10) == 0x00) longout(Start);
  353.         putchar(Blank);
  354.         SwapMMUMode(&origMMUMode);
  355.         databyte = *(UBYTE *)Start;
  356.         SwapMMUMode(&origMMUMode);
  357.         if ((databyte >= Blank) && (databyte <= 0x7e)) AsciiBuf[Aindex++] = databyte;
  358.         else AsciiBuf[Aindex++] = '.';
  359.         Start++;
  360.         byteout(databyte);
  361.         if ((index % 0x10) == 0x0f) {
  362.             AsciiBuf[16] = CR;
  363.             AsciiBuf[17] = Null;
  364.             putchar(Blank);
  365.             putchar(Blank);
  366.             printf("%s",AsciiBuf);
  367.             Aindex = Null;
  368.             }
  369.         } while (++index<Length);
  370.     if ((index % 0x10) != Null) {
  371.         Sindex = 0x10 - (index % 0x10);
  372.         for (index=0;index<Sindex;index++) printf("   ");
  373.         AsciiBuf[Aindex] = Null;
  374.         printf("  ");
  375.         printf("%s",AsciiBuf);
  376.         crlf();
  377.         }
  378.     return(False);
  379.     }
  380.  
  381. UWORD FillMemory() {
  382.     ULONG Start,Length,Value,index;
  383.     UBYTE increment,origMMUMode;
  384.     if (!GetValue()) return(True);
  385.     Start = number;
  386.     if (!GetValue()) return(True);
  387.     Length = number;
  388.     if (Length == 0) Length = 1;
  389.     if (!GetValue()) {
  390.         if (Argument[0] == 'I') {
  391.             increment = True;
  392.             Value = 0;
  393.             }
  394.         else return(True);
  395.         }
  396.     else {
  397.         increment = False;
  398.         Value = number;
  399.         }
  400.     origMMUMode = true32b;
  401.     SwapMMUMode(&origMMUMode);
  402.     for (index=0;index<Length;index++) {
  403.         *(UBYTE *)Start++ = Value;
  404.         if (increment) Value++;
  405.         }
  406.     SwapMMUMode(&origMMUMode);
  407.     return(False);
  408.     }
  409.  
  410. UBYTE WaitForDone(UBYTE slot) {
  411.     ULONG timer = 0x80000,junk;
  412.     junk = (slot24Bit[slot] + Flags);
  413.     while ((PBYTE (slot24Bit[slot] + Flags) & F_ready) && (--timer));
  414.     if (timer) return (False); /* No problem */
  415.     else return(True); /* Timeout */
  416.     }
  417.  
  418. void TransmitData(ULONG buffer, UWORD length, UBYTE slot) {
  419.     PBYTE (slot24Bit[slot] + Command)   = 0x02;   /* Transmit command */
  420.     PWORD (slot24Bit[slot] + Count)     = length; /* Set length          */
  421.     PLONG (slot24Bit[slot] + BufferPtr) = buffer; /* Set address      */
  422.     PBYTE (slot24Bit[slot] + Flags)     = 0x80;   /* Set ready bit      */
  423.     }
  424.  
  425. void ReceiveData(ULONG buffer, UWORD length, UBYTE slot) {
  426.     PBYTE (slot24Bit[slot] + Command)   = 0x04;   /* Receive command  */
  427.     PWORD (slot24Bit[slot] + Count)     = length; /* Set length          */
  428.     PLONG (slot24Bit[slot] + BufferPtr) = buffer; /* Set address      */
  429.     PBYTE (slot24Bit[slot] + Flags)     = 0x80;   /* Set ready bit      */
  430.     }
  431.  
  432. void TestCards() {
  433.     ULONG loopCount;
  434.     UBYTE txerror,rxerror;
  435.     if (GetValue()) loopCount = number;
  436.     else loopCount = 1;
  437.     while (loopCount--) {
  438.         ReceiveData(0x0000A000,1500,ENet2);
  439.         TransmitData(0x00008000,1500,ENet1);
  440.         txerror = WaitForDone(ENet1); /* Wait for transmiter to finish */
  441.         rxerror = WaitForDone(ENet2); /* Wait for receiver to finish */
  442.         if (rxerror) {
  443.             printf("Receiver timeout\n");
  444.             break;
  445.             }
  446.         if (txerror) {
  447.             printf("Transmitter timeout\n");
  448.             break;
  449.             }
  450.         }
  451.     }
  452.  
  453. /*
  454. * Reset the card
  455. * Copy code from main Mac memory into John Galt local memory
  456. * Remove reset
  457. */
  458. #define Miscompare    'M'
  459. #define Timeout        'T'
  460. #define RunFlag        0x4f0
  461. UBYTE Download(UBYTE slot,UBYTE *CodePointer,ULONG Length) {
  462.     UBYTE theMMUMode = true32b;                        /* Set the temproary mode */
  463.     UBYTE error = Null;
  464.     UWORD bucket;                                    /* A place for dummy read */
  465.     ULONG timer;
  466.     volatile UBYTE *Memory = (UBYTE *)slotBases[slot]+0x1000;/* Point to 0xFn010000 for download */
  467.     SwapMMUMode( &theMMUMode );                        /* Set MMU to 32 bit mode */
  468.     *(UWORD *)(slotBases[slot] + ResetMCP) = 0x0000;/* Reset the card */
  469.     *(UWORD *)(slotBases[slot] + 0) = 0x0002;        /* Set the interrupt stack address */
  470.     *(UWORD *)(slotBases[slot] + 2) = 0x0000;        /* Set the interrupt stack address */
  471.     *(ULONG *)(slotBases[slot] + 4) = 0x1000;        /* Set the starting address */
  472.     while (Length--) {
  473.         *Memory = *CodePointer;                        /* Zap Memory */
  474.         if (*Memory++ != *CodePointer++) {            /* Compare source and destination */
  475.             error = Miscompare;
  476.             break;
  477.             }
  478.         }
  479.     PLONG (slotBases[slot] + RunFlag) = 'RobG';        /* Set ready indicator to almost anything */
  480.     bucket = *(UWORD *)(slotBases[slot] + StartMCP);/* Remove the reset and let it live */
  481.     timer = 0x10000;                                /* Set the timeout timer, This is a very long time */
  482.     while ((PLONG (slotBases[slot] + RunFlag) != 'Loop') && (--timer));/* Wait for ready indicator */
  483.     SwapMMUMode( &theMMUMode );                        /* Set MMU back to 24 bit mode */
  484.     if (timer == Null) error = Timeout;
  485.     return(error);                                    /* Return the errors */
  486.     }
  487.  
  488. UBYTE SetUpENetCard(UBYTE slot) {
  489.     UBYTE error    = 0;
  490.     UBYTE *theStartLabel = ( ULONG * )BEGIN;
  491.     ULONG realStart;
  492.     realStart = theStartLabel;
  493.     realStart += 2;
  494.     realStart = *(ULONG *)(realStart);
  495.     (ULONG)theStartLabel = realStart;
  496.     error = Download(slot,theStartLabel,0x2000);
  497.     return(error);
  498.     }
  499.  
  500. void MakeTxPacket(UBYTE slot,UBYTE station,UWORD length) {
  501.     UWORD index;
  502.     UBYTE *SPtr,*DPtr;
  503.     /* Build a packet in local memory */
  504.     for (index=0;index<6;index++) {
  505.         TxPacket.Destination[index] = Node[station].Address[index];
  506.         TxPacket.Source[index] = Node[slot].Address[index];
  507.         }
  508.     if (length > 1500) length = 1500;
  509.     else if (length < 64) length = 64;
  510.     TxPacket.Length = length;
  511.     for (index=0;index<length;index++) {
  512.         TxPacket.Buffer[index] = index;
  513.         }
  514.     /* Copy packet to ENet card memory */
  515.     SPtr = (UBYTE *)&TxPacket;
  516.     DPtr = (UBYTE *)(slotBases[slot] + TxBuffer);
  517.     length += 14; /* Add in the addresses and length fields */
  518.     origMMUMode = true32b;
  519.     SwapMMUMode(&origMMUMode);
  520.     for (index=0;index<length;index++) {
  521.         *DPtr++ = *SPtr++;
  522.         }
  523.     SwapMMUMode(&origMMUMode);
  524.     }
  525.  
  526. void LookForNuBusENet() {
  527.     UBYTE err;
  528.     UWORD index;
  529.     for (index=0;index<6;index++) slot24Bit[index] = False; /* Clear the Pointers */
  530.     slotCount = Null; /* Clear the count */
  531.     SlotBlock.spCatagory = 0x000A;
  532.     SlotBlock.spCType    = 0x0001;
  533.     SlotBlock.spDrvrSW   = 0xFFFF;
  534.     SlotBlock.spDrvrHW   = 0x0002;
  535.     SlotBlock.spSlot     = 0x08;
  536.     SlotBlock.spID       = 0x80;
  537.     do {
  538.         err = SNextTypeSRsrc((SpBlockPtr)&SlotBlock);
  539.         if (err == Null) {
  540.             slot24Bit[slotCount]   = SlotBlock.spSlot * 0x00100000;
  541.             (ULONG)slotBases[slotCount++] = (0xF0000000 + (SlotBlock.spSlot * 0x01000000));
  542.             }
  543.         } while (err == Null);
  544.     for (index=0;index<slotCount;index++) { /* Lets display them for debug */
  545.         err = SetUpENetCard(index);
  546.         if (err) printf("Ethernet card %d has error %02X\n",index,err);
  547.         else {
  548.             MakeTxPacket(index,index + 1,1500); /* Build a packet */
  549.             printf("Ethernet card %d has been initialized\n",index);
  550.             printf("Slot base is %lx\n",slotBases[index]);
  551.             }
  552.         }
  553.     }
  554.  
  555. void Help() {
  556.     printf("?) Print this menu\n");
  557.     printf("A) Alter memory\n");
  558. //    printf("B) \n");
  559. //    printf("C) \n");
  560.     printf("D) Display memory\n");
  561. //    printf("E) \n");
  562.     printf("F) Fill memory\n");
  563. //    printf("G) \n");
  564. //    printf("H) \n");
  565.     printf("I) Alter or display word memory\n");
  566. //    printf("J) \n");
  567. //    printf("K) \n");
  568. //    printf("L) \n");
  569.     printf("M) Go to SONIC menu\n");
  570. //    printf("N) \n");
  571. //    printf("O) \n");
  572. //    printf("P) \n");
  573.     printf("Q) Quit ROBIX\n");
  574. //    printf("R) \n");
  575. //    printf("S) \n");
  576.     printf("T) Test cards using channel commands\n");
  577. //    printf("U) \n");
  578. //    printf("V) \n");
  579. //    printf("W) \n");
  580. //    printf("X) \n");
  581. //    printf("Y) \n");
  582. //    printf("Z) \n");
  583.     }
  584.  
  585. /************************************* Main Loop ********************************************/
  586.  
  587. void main() {
  588.     UBYTE Exit,ExitMode;
  589.     delimiter = CR;
  590.     TabSize = 8;
  591.     Exit = False;
  592.     printf("ROBIX\n");
  593.     LookForNuBusENet(); /* Get the configuration */
  594.     while (!Exit) {
  595.         if (delimiter == CR) putchar('>');
  596.         LineIn();
  597.         ScanDelimiters(); /* Point to first non Blank */
  598.         Upper(&CommandLine[CPointer]);
  599.         switch(CommandLine[CPointer++]) {
  600.             case '?' :
  601.                 Help();
  602.                 break;
  603.             case CR :
  604.                 break;
  605.             case 'A' :
  606.                 if (AlterMemory()) SyntaxError();
  607.                 break;
  608.             case 'B' :
  609.                 BuildPacket(ENet1,ENet2,0x1500); /* Build a packet for ENet 1 */
  610.                 BuildPacket(ENet2,ENet1,0x1500); /* Build a packet for ENet 2 */
  611.                 break;
  612.             case 'C' :
  613.                 break;
  614.             case 'D' :
  615.                 if (DisplayMemory()) SyntaxError();
  616.                 break;
  617.             case 'E' :
  618.                 break;
  619.             case 'F' :
  620.                 if (FillMemory()) SyntaxError();
  621.                 break;
  622.             case 'G' :
  623.                 break;
  624.             case 'H' :
  625.                 break;
  626.             case 'I' :
  627.                 if (AlterWordMemory()) SyntaxError();
  628.                 break;
  629.             case 'J' :
  630.                 break;
  631.             case 'K' :
  632.                 break;
  633.             case 'L' :
  634.                 break;
  635.             case 'M' :
  636.                 ExitMode = SONICMenu();
  637.                 if (ExitMode == 'Q') Exit = True;
  638.                 break;
  639.             case 'N' :
  640.                 break;
  641.             case 'O' :
  642.                 break;
  643.             case 'P' :
  644.                 break;
  645.             case 'Q' :
  646.                 Exit = True;
  647.                 printf("Bye...\n");
  648.                 break;
  649.             case 'R' :
  650.                 break;
  651.             case 'S' :
  652.                 break;
  653.             case 'T' :
  654.                 TestCards();
  655.                 break;
  656.             case 'U' :
  657.                 break;
  658.             case 'V' :
  659.                 break;
  660.             case 'W' :
  661.                 break;
  662.             case 'X' :
  663.                 break;
  664.             case 'Y' :
  665.                 break;
  666.             case 'Z' :
  667.                 break;
  668.             default :
  669.                 printf("Unknown command\n");
  670.                 delimiter = CR;
  671.                 break;
  672.             }
  673.         }
  674.     }
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.